"""
Factory for creating cloud storage clients.

This module provides a factory function to create cloud storage clients
for different providers.
"""

from typing import Dict, Type, Any, Optional

from .base.client import CloudStorageClient
# 暂时禁用未验证的网盘提供商
# from .providers.baidu.client import BaiduClient
# from .providers.aliyun.client import AliyunClient
# from .providers.onedrive.client import OneDriveClient
# from .providers.google_drive.client import GoogleDriveClient
# from .providers.tianyi.client import TianyiClient
# from .providers.tianyi_pc.client import TianyiPCClient  # 暂时禁用，实现未完成
from .providers.tianyi_tv.client import TianyiTVClient
from .constants import PROVIDER_BAIDU, PROVIDER_ALIYUN, PROVIDER_ONEDRIVE, PROVIDER_GOOGLE_DRIVE, PROVIDER_TIANYI, PROVIDER_TIANYI_PC, PROVIDER_TIANYI_TV


class CloudStorageClientWrapper(CloudStorageClient):
    """
    包装器类，确保只暴露基类接口，屏蔽具体实现细节
    """
    
    def __init__(self, wrapped_client: CloudStorageClient):
        # 调用父类初始化，但不设置_logged_in状态
        super().__init__()
        self._wrapped_client = wrapped_client
    
    def __getattr__(self, name: str) -> Any:
        """
        将所有方法调用转发到包装的客户端实例
        只允许访问基类中定义的方法
        """
        # 获取基类的所有公共方法
        base_class_methods = set(dir(CloudStorageClient))
        
        # 检查请求的属性是否在基类中
        if name in base_class_methods:
            return getattr(self._wrapped_client, name)
        
        # 如果不是基类方法，则拒绝访问
        raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")
    
    def __setattr__(self, name: str, value: Any) -> None:
        """
        控制属性设置，只允许设置基类中定义的属性
        """
        # 对于内部属性，允许设置
        if name.startswith('_'):
            super().__setattr__(name, value)
            return
        
        # 获取基类的所有公共属性
        base_class_attributes = set(dir(CloudStorageClient))
        
        # 检查请求的属性是否在基类中
        if name in base_class_attributes:
            setattr(self._wrapped_client, name, value)
        else:
            raise AttributeError(f"Cannot set attribute '{name}' as it's not defined in the base class")
    
    # 实现所有抽象方法，转发到包装的客户端
    def trigger_login(self, credentials):
        return self._wrapped_client.trigger_login(credentials)
    
    def check_login_status(self, session_id):
        return self._wrapped_client.check_login_status(session_id)
    
    def serialize_login_info(self):
        return self._wrapped_client.serialize_login_info()
    
    def restore_login_from_string(self, serialized_info):
        return self._wrapped_client.restore_login_from_string(serialized_info)
    
    def get_account_info(self):
        return self._wrapped_client.get_account_info()
    
    def list_files(self, folder_id=None):
        return self._wrapped_client.list_files(folder_id)
    
    def create_folder(self, name, parent_id=None):
        return self._wrapped_client.create_folder(name, parent_id)
    
    def upload_file(self, file_name, file_data, parent_id=None, overwrite=False, progress_callback=None):
        return self._wrapped_client.upload_file(file_name, file_data, parent_id, overwrite, progress_callback)
    
    def delete_file(self, file_id):
        return self._wrapped_client.delete_file(file_id)
    
    def move_file(self, file_id, new_parent_id, folder_id=None):
        return self._wrapped_client.move_file(file_id, new_parent_id, folder_id)
    
    def rename_file(self, file_id, new_name):
        return self._wrapped_client.rename_file(file_id, new_name)
    
    def get_file_info(self, file_id, folder_id):
        return self._wrapped_client.get_file_info(file_id, folder_id)
    
    def search_files(self, query):
        return self._wrapped_client.search_files(query)
    
    def list_trash(self):
        return self._wrapped_client.list_trash()
    
    def empty_trash(self):
        return self._wrapped_client.empty_trash()
    
    def get_download_url(self, file_id):
        return self._wrapped_client.get_download_url(file_id)
    
    def check_fast_upload(self, file_name, file_data):
        return self._wrapped_client.check_fast_upload(file_name, file_data)
    
    def fast_upload_file(self, file_name, file_data, parent_id=None):
        return self._wrapped_client.fast_upload_file(file_name, file_data, parent_id)
    
    @property
    def is_logged_in(self) -> bool:
        return self._wrapped_client.is_logged_in


class CloudStorageClientFactory:
    """
    Factory class for creating cloud storage clients.
    """
    
    _client_registry: Dict[str, Type[CloudStorageClient]] = {
        # 暂时禁用未验证的网盘提供商
        # PROVIDER_BAIDU: BaiduClient,
        # PROVIDER_ALIYUN: AliyunClient,
        # PROVIDER_ONEDRIVE: OneDriveClient,
        # PROVIDER_GOOGLE_DRIVE: GoogleDriveClient,
        # PROVIDER_TIANYI: TianyiClient,
        # PROVIDER_TIANYI_PC: TianyiPCClient,  # 暂时禁用，实现未完成
        PROVIDER_TIANYI_TV: TianyiTVClient,
    }
    
    @classmethod
    def create_client(cls, provider: str) -> CloudStorageClient:
        """
        Create a cloud storage client for the specified provider.
        
        Args:
            provider: The name of the cloud storage provider
            
        Returns:
            CloudStorageClient: An instance of the appropriate client wrapped in a base class interface
            
        Raises:
            ValueError: If the provider is not supported
        """
        if provider not in cls._client_registry:
            raise ValueError(f"Unsupported provider: {provider}. Supported providers: {list(cls._client_registry.keys())}")
        
        client_class = cls._client_registry[provider]
        actual_client = client_class()
        
        # 返回包装后的客户端，确保只暴露基类接口
        return CloudStorageClientWrapper(actual_client)
    
    @classmethod
    def register_client(cls, provider: str, client_class: Type[CloudStorageClient]) -> None:
        """
        Register a new client class for a provider.
        
        Args:
            provider: The name of the cloud storage provider
            client_class: The client class to register
        """
        cls._client_registry[provider] = client_class
    
    @classmethod
    def get_supported_providers(cls) -> list:
        """
        Get a list of supported providers.
        
        Returns:
            list: List of supported provider names
        """
        return list(cls._client_registry.keys())


def create_cloud_storage_client(provider: str) -> CloudStorageClient:
    """
    Create a cloud storage client for the specified provider.
    
    This is a convenience function that uses CloudStorageClientFactory.
    
    Args:
        provider: The name of the cloud storage provider
        
    Returns:
        CloudStorageClient: An instance of the appropriate client wrapped in a base class interface
        
    Raises:
        ValueError: If the provider is not supported
    """
    return CloudStorageClientFactory.create_client(provider)